#include <stdio.h>
#include <stdlib.h>

typedef unsigned __int64 size_t;
typedef unsigned char   uint8_t;

typedef struct A_BLOCK_LINK{
    struct A_BLOCK_LINK *pxNextFreeBlock;
    size_t xBlockSize;
}BlockLink_t;

static BlockLink_t xStart;
static BlockLink_t * pxEnd = NULL;
//加入空闲块代码
void InsertBlockIntoFreeList(BlockLink_t *pxBlockToInster)
{
    BlockLink_t *pxInterator;
    uint8_t *puc;
    //遍历空闲列表，找到插入空闲块的位置
    for(pxInterator = &xStart; pxInterator->pxNextFreeBlock<pxBlockToInster;pxInterator=pxInterator->pxNextFreeBlock)
    {
        ;
    }
    //如果要插入的空闲块在当前空闲块的后面
    puc = (uint8_t *)pxInterator;
    //判断当前代码块是否和插入的代码块相邻，如果相邻，合并空闲块。
    if( puc + pxInterator->xBlockSize == (uint8_t *)pxBlockToInster)
    {
        pxInterator->xBlockSize +=  pxBlockToInster->xBlockSize;
        pxBlockToInster = pxInterator; 
    }
    //判断言插入的空闲块是否和当前空闲块的下一个空闲块相连接。
    puc = (uint8_t *)pxBlockToInster;

    if(puc + pxBlockToInster->xBlockSize == (uint8_t *)pxInterator->pxNextFreeBlock)
    {
        if(pxInterator->pxNextFreeBlock != pxEnd)
        {
            pxBlockToInster->xBlockSize += pxInterator->pxNextFreeBlock->xBlockSize;
            pxBlockToInster->pxNextFreeBlock = pxInterator->pxNextFreeBlock;
        }
    }
    else
    {
        pxBlockToInster->pxNextFreeBlock = pxInterator->pxNextFreeBlock;
    }
    //如果要插入的空闲块没有和当前空闲块相连接
    if(pxInterator != pxBlockToInster)
    {
        pxInterator->pxNextFreeBlock = pxBlockToInster;
    }
}
//初始化空闲块链表
void InitializeFreelist(size_t initialSize)
{
    xStart.pxNextFreeBlock = NULL;
    xStart.xBlockSize = 0;

    pxEnd = (BlockLink_t *)malloc(sizeof(BlockLink_t));
    pxEnd->pxNextFreeBlock = NULL;
    pxEnd->xBlockSize = 0;

    BlockLink_t *initialBlock = (BlockLink_t *)malloc(sizeof(BlockLink_t));
    initialBlock->pxNextFreeBlock = pxEnd;
    initialBlock->xBlockSize = initialSize;

    xStart.pxNextFreeBlock = initialBlock;
}
//用于打印当前空前快的大小
void PrintFreeList()
{
    BlockLink_t *pxIterator = xStart.pxNextFreeBlock;
    while(pxIterator != pxEnd)
    {
        printf("Block Size :$llu\n",pxIterator->xBlockSize);
        pxIterator = pxIterator->pxNextFreeBlock;
    }
}

int main(){
    InitializeFreelist(100);
    
    BlockLink_t *newBlock1 = (BlockLink_t *)malloc(sizeof(BlockLink_t));
    newBlock1->xBlockSize = 50;
    InsertBlockIntoFreeList(newBlock1);

    BlockLink_t *newBlock2 = (BlockLink_t *)malloc(sizeof(BlockLink_t));
    newBlock2->xBlockSize = 70;
    InsertBlockIntoFreeList(newBlock2);

    PrintFreeList();
    return 0;
}